package com.golxen.framework.common.server.game.sync.message;


import com.golxen.framework.CrossProtocol;
import com.golxen.framework.PBPacket.PBPacket;
import com.golxen.framework.PBPacket.PBPacketUtils;
import com.golxen.framework.common.server.game.GameServer;
import com.golxen.framework.netty.session.game.GameServerLinkedSet;
import com.golxen.protojava.SyncMessage;
import com.google.protobuf.ByteString;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.golxen.framework.manager.TempMgr;

import java.util.concurrent.CompletableFuture;

//使用completableFuture进行非阻塞的同步(可组合式异步编程，多个completableFuture合在一起再来个completableFuture最终处理)
public class SyncServiceMgr extends TempMgr {

    private static final GameSyncCmdService syncMessageService = new GameSyncCmdService();
    private static final SyncMessageDispatcher dispatcher = new SyncMessageDispatcher();

    public boolean reload() throws Exception {
    	initGameServiceCommand();
    	return true;
    }

    /**
     * 初始化
     */
    public static void initGameServiceCommand() {
//        syncMessageService.addGameServiceCommand(GameProtocol.XXX, new XXXCmd());

    }

    public static GameSyncCmdService getSyncMessageService() {
        return syncMessageService;
    }



    public static CompletableFuture<SyncResponse> sendToActivityCrossServer(long userId, int code, int activityId, GeneratedMessage.Builder<?> requestBuilder, GeneratedMessage.Builder<?> responseBuilder) {
        long serverId = GameServer.getInstance().getServerId();
        SyncResultProcessor resultProcessor = sendMsgSync(serverId, 0, userId, code, CrossProtocol.C_CROSS_SERVICE_HANDLER, activityId, requestBuilder, responseBuilder);
        PBPacket request = resultProcessor.getRequest();
        GameServerLinkedSet.send(0, request);
        return resultProcessor.getCompletableFuture();
    }

    public static CompletableFuture<SyncResponse> sendToGameServer(long forwardServerId, int code, long userId, GeneratedMessage.Builder<?> requestBuilder, GeneratedMessage.Builder<?> responseBuilder) {
        long serverId = GameServer.getInstance().getServerId();
        SyncResultProcessor resultProcessor = sendMsgSync(serverId, forwardServerId, userId, code, CrossProtocol.C_SERVICE_FORWARD_MESSAGE, 0, requestBuilder, responseBuilder);
        PBPacket request = resultProcessor.getRequest();
        GameServerLinkedSet.send(0, request);
        return resultProcessor.getCompletableFuture();
    }


    public static SyncResultProcessor sendMsgSync(long rawServerId, long forwardServerId, long userId, int code, int sCode,
                                              int activityId, GeneratedMessage.Builder<?> requestBuilder, GeneratedMessage.Builder<?> responseBuilder) {
        SyncMessage.Request.Builder builder = SyncMessage.Request.newBuilder();
        builder.setCmdCode(code);
        if (requestBuilder != null) {
            ByteString byteString = requestBuilder.build().toByteString();
            builder.setDataBytes(byteString);
        }
        builder.setActivityId(activityId);
        builder.setRawServerId(rawServerId);
        builder.setForwardServerId(forwardServerId);
        builder.setSenderId(userId);
        SyncResultProcessor resultProcessor = dispatcher.pending(builder);
        resultProcessor.setResponseBuilder(responseBuilder);
        PBPacket buildMessage = PBPacketUtils.buildMessage(sCode, 0, builder);
        resultProcessor.setRequest(buildMessage);
        return resultProcessor;
    }

    public static void receiveMsgHandler(PBPacket packet) {
        try {
            SyncMessage.Response response = SyncMessage.Response.parseFrom(packet.getBytes());
            dispatcher.receive(response);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

    }

    public static void scheduleClean() {
        dispatcher.scheduleCleanResultProcessor();
    }

}
